package com.chen.framework.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.framework.model.sys.SysDir;
import com.chen.framework.vo.SysDirVO;
import com.chen.base.utils.ConvertUtil;
import com.chen.base.utils.StreamUtil;
import com.chen.framework.mapper.SysDirMapper;
import com.chen.framework.service.inter.SysDirService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <p>
 * 系统目录 服务实现类
 * </p>
 *
 * @author 
 * @since 2024-11-28 03:02:28
 */
@Slf4j
@Service
public class SysDirServiceImpl extends ServiceImpl<SysDirMapper, SysDir> implements SysDirService {

    @Override
    public List<SysDirVO> treeSysDirList() {
        List<SysDir> sysDirs = baseMapper.selectList(Wrappers.lambdaQuery());
        // 创建一个List集合来存放最终的树状结构数据
        List<SysDirVO> dirList = new ArrayList<>();
        // 先存入最顶级的树（0代表没有父级，即最顶级），然后通过最顶级的id递归获取子级
        Iterator<SysDir> iterator = sysDirs.iterator();
        while (iterator.hasNext()){
            SysDir sysDir = iterator.next();
            if (sysDir.getParentId() != null && sysDir.getParentId() == 0){
                // 删除当前顶级目录，避免死循环
                iterator.remove();

                SysDirVO vo = getChildren(sysDirs, sysDir);
                dirList.add(vo);
            }
        }

        return sorted(dirList);
    }

    /**
     * 递归处理：通过id获取子级，查询子级下的子级
     *
     * @param sysDirs 数据库的原始数据
     * @param parent   父级
     * @return  该id下的子级
     */
    private SysDirVO getChildren(List<SysDir> sysDirs, SysDir parent) {
        SysDirVO parentVo = ConvertUtil.convertor(parent, SysDirVO.class);
        List<SysDirVO> sonDirList = new ArrayList<>();

        for (SysDir sysDir : sysDirs) {
            // 如果本级id与数据的父id相同，就说明是子父级关系
            if (sysDir.getParentId() != null && parent.getId().equals(sysDir.getParentId())) {
                SysDirVO vo = getChildren(sysDirs, sysDir);
                sonDirList.add(vo);
            }
        }

        parentVo.setSonDirList(sorted(sonDirList));
        return parentVo;
    }

    /**
     * 按同级序号正序
     */
    private List<SysDirVO> sorted(List<SysDirVO> list) {
        return StreamUtil.sort(list, SysDirVO::getSerialNum, true);
    }
}
